﻿using Core.Framework.Model.Common;
using Core.Framework.Model.WebSockets;
using Core.Framework.Redis.Queue_Helper;
using Core.Framework.Util;
using Core.Service.TaskHandle.Task_Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Threading;

namespace Core.Service.TaskHandle.Task_Listener
{
    /// <summary>
    /// Template = WebSocketMidWare.Template
    /// [需保持一致]
    /// </summary>
    [Listenner(Template = "WebSocket")]
    public class WebSocket_Linstener : BaseMQMsgListener, IMQMsgListener
    {
        public DoWork_Out DoWork(MessageQueue messageQueue)
        {
            try
            {

                int.TryParse(messageQueue.Message.Channel, out int userKey);

                // 是否是系统用户
                bool isSystemUser = userKey > 0;


                // 构造发送消息
                var json = this.StructureParameter(messageQueue);

                // 是否点对点
                var isSingle = messageQueue.Message.MessageType.Equals(MessageTypeEnum.Single);

                // 构造返回数据
                var outModel = new DoWork_Out
                {
                    OK = true,
                    Message = messageQueue,
                    Action = isSingle ? "SingleNull" : "GroupNull"
                };

                // 获取消息组
                var channleHashName = 
                    WebSocketApplication.GetChannleHashName(messageQueue.ClientInfo, messageQueue.Message.Channel);




                // *** 检查是否存在该消息订阅用户组 ***
                if (!WebSocketApplication.ChannlesPool.ContainsKey(channleHashName))
                {
                    this.AddLogConsumFail(messageQueue);
                    return outModel;
                }


                // 项目Token
                var projectToken = messageQueue.ClientInfo.Project.ProjectToken;



                // 获取订阅客户端ID
                List<string> clientIds = WebSocketApplication.ChannlesPool[channleHashName];

                // 获取当前有效会话
                List<WebSocket> wss = this.GetWebSocketListByClientIds(projectToken, clientIds);



                // *** 检查是否存在该消息订阅用户组 ***
                if (wss.Count == 0)
                {
                    this.AddLogConsumFail(messageQueue);
                    return outModel;
                }

                // 如果是单聊只发送一个随机用户
                if (isSingle && wss.Count > 1)
                {
                    Random rd = new Random();
                    wss = new List<WebSocket> { wss[rd.Next(wss.Count)] };
                }


                foreach (var client in wss)
                {
                    try
                    {
                        base.SendMessage(client, json);
                        outModel.Action = "";
                        Thread.Sleep(300);
                        this.AddLogConsum(messageQueue , json);
                    }
                    catch (Exception e)
                    {
                        outModel.OK = false;
                        outModel.Parameters = new object[] { e.Message, 2000 };
                        outModel.Action = "error";

                        WebSocketApplication.ClientLoginOut(client);

                        this.AddLogConsumError(messageQueue, e.Message);
                    }
                }

                return outModel;

            }
            catch (Exception e)
            {
                this.AddLogWebSocketError(messageQueue, e.Message);

                return new DoWork_Out
                {
                    OK = false,
                    Parameters = new object[] {e.Message, 2000},
                    Action = "error"
                };
            }
        }

        public void Errer(DoWork_Out model)
        {
            RedisQueueHelper.SortedPush(
                RedisQueueHelperParameter.Queue, 
                JsonConvert.SerializeObject(model.Message),
                (double)model.Parameters[1]);
        }

        public void Success(DoWork_Out model)
        {

            // 1. 存储在 redis list
            // 2. 满 （10 -100） / 条 写入数据库
            // 3. 用户登录 查询 redis list 存在即移除
            // 4. 数据量较小时 每10分钟查询 redis list 存入数据库

            // case "GroupNull":
            // case "SingleNull":
            if (model.Action.Equals("SingleNull"))
                RedisQueueHelper.ListPush(RedisQueueHelperParameter.SingleNull, JsonConvert.SerializeObject(model.Message));

            RedisQueueHelper.ListPush(
                RedisQueueHelperParameter.History,
                JsonConvert.SerializeObject(model.Message));

        }

    }
}
